package cn.dengta.webapp.user.entity;

import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

import cn.dengta.common.model.ValueProxy;
import cn.dengta.common.model.ValueProxyImpl;
import cn.dengta.context.model.Option;
import cn.dengta.context.model.WesKit;
import cn.dengta.webapp.base.entity.BizEntity;
import cn.dengta.webapp.base.entity.I18nContent;
import cn.dengta.webapp.user.model.Gender;
import cn.dengta.webapp.user.model.Global;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import me.codeplayer.util.*;

/**
 * 标签
 *
 * @author lgy
 * @since 2022-08-06
 */
@Setter
@Getter
@Accessors(chain = true)
@TableName("dt_tag")
public class Tag extends BizEntity {

	/** 添加用户 */
	private Long addUserId;
	/** 名称 */
	private String name;
	/** 类型 */
	private TagType type;
	/** 子类型 SubTagType */
	private Integer subType;
	/** 描述 */
	private String summary;
	/** 图标 */
	private String image;
	/** 性别：0=女；1=男 */
	@Nullable
	private Gender gender;
	@Nullable
	private Global global;
	/** 所属分包 */
	private String wesKits;
	/** 发布时间 */
	private Date openTime;
	/** 排序 */
	private Integer sort;
	/** 使用数 */
	private Long useCount;
	protected transient I18nContent resolvedLanguageCfg;

	public Tag init(Tag input, Date now) {
		this.addUserId = X.expectNotNull(addUserId, input.addUserId);
		this.name = X.expectNotNull(input.name, name);
		this.gender = input.gender;
		this.global = input.global;
		this.type = X.expectNotNull(type, input.type);
		this.subType = X.expectNotNull(input.subType, subType);
		this.summary = StringUtil.toString(input.summary);
		this.wesKits = input.wesKits;
		this.image = StringUtil.toString(input.image);
		this.openTime = X.expectNotNull(input.openTime, openTime, now);
		this.sort = X.expectNotNull(input.sort, sort, 0);
		super.init(input.status, input.state);
		super.initTime(now);
		return this;
	}

	public boolean isOpen(Long baseTime) {
		if (baseTime == null) {
			baseTime = System.currentTimeMillis();
		}
		return isEnabled() && openTime != null && baseTime >= openTime.getTime();
	}

	@Nullable
	public I18nContent getResolvedLanguageCfg() {
		I18nContent cfg = resolvedLanguageCfg;
		if (type.i18n && cfg == null) {
			resolvedLanguageCfg = cfg = StringUtil.isEmpty(name) ? null : I18nContent.deserialize(name);
		}
		return cfg;
	}

	public boolean hasWesKit(WesKit wesKit) {
		if (StringUtil.notEmpty(this.wesKits)) {
			return WesKit.isWesKit(wesKit, this.wesKits);
		}
		return false;
	}

	public String i18nName() {
		return type.i18n ? X.map(getResolvedLanguageCfg(), I18nContent::get) : name;
	}

	@Override
	public boolean isEnabled() {
		return this.status > 0;
	}

	public static Map<String, Object> asEmbed(final Tag tag) {
		return asEmbed(tag, t -> CollectionUtil.ofHashMap("id", t.getId(), "name", t.getName()));
	}

	@Getter
	public enum TagType implements ValueProxyImpl<TagType, Integer> {

		MOMENT(0, "动态", false, true, -1, false),
		USER_TAG(1, "魅力标签", true, true, -1, false),
		LIKE_GENRE(2, "专属缘分", true, true, -1, false),
		AUDIO_EVAL(3, "语音评价", true, false, 6, false),
		VIDEO_EVAL(4, "视频评价", true, false, 6, false),
		AI_IDENTITY(5, "身份设定", true, true, -1, false),
		AI_RELATION(6, "关系设定", true, true, -1, false),
		AI_TAG(7, "AI标签", true, true, 10, true),
		//
		;

		public final Integer value;
		public final Integer limitCount;
		public final boolean show;
		public final boolean i18n;
		public final boolean random;
		final ValueProxy<TagType, Integer> proxy;

		TagType(Integer value, String label, boolean i18n, boolean show, Integer limitCount, boolean random) {
			this.value = value;
			this.i18n = i18n;
			this.show = show;
			this.limitCount = limitCount;
			this.random = random;
			this.proxy = new ValueProxy<>(this, value, label);
		}

		public static TagType getValueByName(String name) {
			for (TagType type : getValues()) {
				if (type.name().equalsIgnoreCase(name)) {
					return type;
				}
			}
			return null;
		}

		public static TagType[] CACHE = Arrays.stream(values()).filter(TagType::isShow).toArray(TagType[]::new);
		public static final TagType[] AI_CACHE = Arrays.stream(values()).filter(e -> ArrayUtil.ins(e, AI_TAG, AI_IDENTITY, AI_RELATION)).filter(TagType::isShow).toArray(TagType[]::new);

		public static TagType[] getValues() {
			return ValueProxy.getCachedArray(TagType.class, TagType::values);
		}

		public static TagType of(Integer value) {
			return MOMENT.getValueOf(value);
		}

		public boolean isAi() {
			return ArrayUtil.ins(this, AI_CACHE);
		}
	}

	@Getter
	public enum SubTagType implements ValueProxyImpl<SubTagType, Integer> {
		ME_TAG(1, "我的标签", TagType.USER_TAG),
		INTEREST_TAG(2, "兴趣爱好", TagType.USER_TAG),
		;
		@EnumValue
		public Integer value;
		public TagType parent;
		public ValueProxy<SubTagType, Integer> proxy;

		SubTagType(Integer value, String label, TagType parent) {
			this.value = value;
			this.parent = parent;
			this.proxy = new ValueProxy<>(this, value, label);
		}

		public static List<Option<Integer>> SUB_TAG_TYPE_CACHE = Arrays.asList(values()).stream().map(t ->
				new Option<>(t.value, t.getLabel(), Long.parseLong(t.parent.getValue().toString()))).collect(Collectors.toList());

		public static final SubTagType of(Integer value) {
			return INTEREST_TAG.getValueOf(value);
		}
	}

	public static final String ADD_USER_ID = "add_user_id";
	public static final String NAME = "name";
	public static final String TYPE = "type";
	public static final String GENDER = "gender";
	public static final String GLOBAL = "global";
	public static final String OPEN_TIME = "open_time";
	public static final String SUMMARY = "summary";
	public static final String IMAGE = "image";
	public static final String SORT = "sort";

}
